package com.spark.lola.logistics.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.spark.lola.logistics.entity.CarSubscribe;
import com.spark.lola.logistics.entity.Message;
import com.spark.lola.logistics.entity.OrderInfo;
import com.spark.lola.logistics.mapper.CarInfoMapper;
import com.spark.lola.logistics.mapper.CarSubscribeMapper;
import com.spark.lola.logistics.service.CarSubscribeService;
import com.spark.lola.logistics.service.MessageService;
import com.spark.lola.logistics.util.RedisManage;
import com.spark.lola.support.common.constant.CommonConstant;
import com.spark.lola.support.common.entity.ShiroUser;
import com.spark.lola.support.mybatis.entity.PageParam;
import com.spark.lola.support.mybatis.entity.QueryParam;
import com.spark.lola.support.mybatis.service.impl.BaseServiceImpl;
import com.spark.lola.support.wms.configuration.JPushProperties;
import com.spark.lola.support.wms.constant.KafkaTopic;
import com.spark.lola.support.wms.constant.OrderType;
import com.spark.lola.support.wms.dto.JPushSendDto;
import com.spark.lola.support.wms.dto.OrderDto;
import com.spark.lola.support.wms.util.JPushUtil;
import io.netty.channel.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.Date;
import java.util.Set;

/**
 * @author: Zhi-peng wang
 * @date: 2020/05/11 19:36
 * 回头车预订业务接口实现
 **/
@Service
public class CarSubscribeServiceImpl extends BaseServiceImpl<CarSubscribeMapper, CarSubscribe> implements CarSubscribeService {

    private static final Logger logger = LoggerFactory.getLogger(CarSubscribeServiceImpl.class);

    @Autowired
    private CarSubscribeMapper carSubscribeMapper;

    @Autowired
    private CarInfoMapper carInfoMapper;

    @Autowired
    private KafkaTemplate kafkaTemplate;


    @Override
    public IPage<CarSubscribe> findPage(QueryParam<CarSubscribe> queryParam) {
        PageParam<CarSubscribe> pageParam = queryParam.toPageParam();
        return carSubscribeMapper.findPage(pageParam.getPage(), pageParam.getEntityWrapper());
    }

    @Override
    public boolean addCarSubscribe(OrderInfo orderInfo, ShiroUser shiroUser) {
        CarSubscribe carSubscribe = new CarSubscribe();
        carSubscribe.setDrivingId(orderInfo.getCreatorId());
        carSubscribe.setDrivingName(shiroUser.getRealName());
        carSubscribe.setDrivingPhone(shiroUser.getPhone());
        carSubscribe.setCarId(orderInfo.getCarId());
        carSubscribe.setCarNo(carInfoMapper.findNoById(orderInfo.getCarId()));
        carSubscribe.setStartAreaIds(orderInfo.getStartAreaIds());
        carSubscribe.setStartArea(orderInfo.getStartArea());
        carSubscribe.setStartAddress(orderInfo.getStartAddress());
        carSubscribe.setEndAreaIds(orderInfo.getEndAreaIds());
        carSubscribe.setEndArea(orderInfo.getEndArea());
        carSubscribe.setEndAddress(orderInfo.getEndAddress());
        return carSubscribeMapper.insert(carSubscribe) != 0;
    }

    @Override
    public boolean updateCarSubscribeUsed(long driverId) {
        return carSubscribeMapper.updateUsedByDriverId(CommonConstant.N, new Date(), driverId) != 0;
    }

    @Override
    public void subscriber(long carSubscribeId, String remark, long subscribeId, String subscribeName, ShiroUser shiroUser) throws Exception {
        CarSubscribe carSubscribe = carSubscribeMapper.selectById(carSubscribeId);
        logger.info("====【{}】预订回头车【{}】===START===", subscribeName, carSubscribe.getCarNo());
        if (!CommonConstant.W.equals(carSubscribe.getUsed())) {
            logger.info("====回头车预订（状态错误）失败===END===");
            throw new Exception("状态错误");
        }
        CarSubscribe info = new CarSubscribe();
        info.setId(carSubscribe.getId());
        info.setUsed(CommonConstant.C);
        info.setSubscribeId(subscribeId);
        info.setSubscribePhone(shiroUser.getPhone());
        info.setSubscribeName(subscribeName);
        info.setSubscribeTime(new Date());
        info.setRemark(remark);
        info.setVersion(carSubscribe.getVersion());
        if (carSubscribeMapper.updateById(info) == 0) {
            logger.info("====回头车预订（更新失败）失败===END===");
            throw new Exception("预订失败");
        }
        info.setCarNo(carSubscribe.getCarNo());
        sendSubscribeChange(info, 0, "预订回头车申请已提交！",
                String.format("【%s】预订回头车【%s】申请已提交", subscribeName, carSubscribe.getCarNo()));
        logger.info("====回头车预订成功===END===");
    }

    @Override
    public void audio(long carSubscribeId, String msg, boolean isPass, ShiroUser shiroUser) throws Exception {
        CarSubscribe carSubscribe = carSubscribeMapper.selectById(carSubscribeId);
        logger.info("====【{}】审核【{}】预订的回头车【{}】===START===", shiroUser.getRealName(), carSubscribe.getSubscribeName(), carSubscribe.getCarNo());
        if (!CommonConstant.C.equals(carSubscribe.getUsed())) {
            logger.info("====回头车预订审核（状态错误）失败===END===");
            throw new Exception("状态错误");
        }
        String message;
        String adminMessage;
        int type;
        if (isPass) {
            CarSubscribe info = new CarSubscribe();
            info.setId(carSubscribe.getId());
            info.setUsed(CommonConstant.Y);
            info.setVersion(carSubscribe.getVersion());
            if (carSubscribeMapper.updateById(info) == 0) {
                logger.info("====回头车预订审核通过（更新失败）失败===END===");
                throw new Exception("回头车预订审核通过（更新失败）失败");
            }
            message = String.format("%s同意了你预订的回头车", shiroUser.getRealName());
            adminMessage = String.format("【%s】审核【%s】预订的回头车【%s】通过", shiroUser.getRealName(), carSubscribe.getSubscribeName(), carSubscribe.getCarNo());
            type = 1;
        } else {
            if (carSubscribeMapper.cancelUpdate(CommonConstant.W, carSubscribe.getId(),
                    carSubscribe.getVersion() + 1, carSubscribe.getVersion()) == 0) {
                logger.info("====回头车预订审核不通过（更新失败）失败===END===");
                throw new Exception("回头车预订审核不通过（更新失败）失败");
            }
            message = String.format("%s未同意你的预约，原因：%s", shiroUser.getRealName(), msg);
            adminMessage = String.format("【%s】审核【%s】预订的回头车【%s】不通过", shiroUser.getRealName(), carSubscribe.getSubscribeName(), carSubscribe.getCarNo());
            type = 2;
        }
        sendSubscribeChange(carSubscribe, type, message, adminMessage);
        logger.info("====回头车预订审核操作 成功===END===");
    }

    @Override
    public void cancel(long carSubscribeId, long subscribeId) throws Exception {
        CarSubscribe carSubscribe = carSubscribeMapper.selectById(carSubscribeId);
        logger.info("====【{}】取消预订回头车【{}】===START===", carSubscribe.getSubscribeName(), carSubscribe.getCarNo());
        if (carSubscribe.getSubscribeId() != subscribeId) {
            logger.info("====取消回头车预订（非法操作）失败===END===");
            throw new Exception("非法操作");
        }
        if (!CommonConstant.Y.equals(carSubscribe.getUsed())) {
            logger.info("====取消回头车预订（状态错误）失败===END===");
            throw new Exception("状态错误");
        }
        if (carSubscribeMapper.cancelUpdate(CommonConstant.W, carSubscribe.getId(),
                carSubscribe.getVersion() + 1, carSubscribe.getVersion()) == 0) {
            logger.info("====回头车预订（更新失败）失败===END===");
            throw new Exception("更新失败");
        }
        sendSubscribeChange(carSubscribe, 3, "回头车预订已取消！",
                String.format("【%s】取消预订回头车【%s】成功", carSubscribe.getSubscribeName(), carSubscribe.getCarNo()));
        logger.info("====回头车预订成功===END===");
    }

    private void sendSubscribeChange(CarSubscribe carSubscribe, Integer type, String message, String msg) {
        logger.info("===推送预订消息...");
        OrderDto<CarSubscribe> param = new OrderDto<>(OrderType.CAR_SUBSCRIBE, carSubscribe, msg, message);
        try {
            kafkaTemplate.send(KafkaTopic.LOGISTICS_CAR_SUBSCRIBE_CHANGE, type.toString(), JSON.toJSONString(param));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
